# 使用蓝图
from . import pap_bp
from flask import request,abort, make_response,jsonify,current_app
from info.utils.captcha.captcha import captcha
from info import redis_store, constants
from info.utils.response_code import RET
import json
import re
from info.models import User
import random
from info.lib.yuntongxun.sms import CCP

# from . import passport_bp
# from flask import request, abort, make_response, jsonify, current_app
# from info.utlis.captcha.captcha import captcha
# from info import redis_store, constants
# import json
# from info.utlis.response_code import RET
# import re
# from info.models import User
# from info.lib.yuntongxun.sms import CCP
# import random
#
# # GET: 127.0.0.1:5000/passport/image_code
# @passport_bp.route('/image_code')

"""
步骤：
１．获取参数
２．验证参数
３．处理逻辑
４．响应返回
"""

"""第一步前端生成一个UUID编码，将其发送给后端，后端获取到之后，生成一个图片对象，把这个图片验证码的真实值和这个UUID组成一个键值对，保存到redis数据库中，然后向前端返回一个验证码图片"""
# 点击注册是弹出注册窗时,前端会向后端链接验证码图片
@pap_bp.route("/image_code")
def get_image_code():
    """获取参数"""
    # 1,1 获取前端传上来的随机UUID编码　imageCodeId
    imageCodeId = request.args.get('imageCodeId')

    #2,校验参数
    #2,2 UUID编码是否为空　imageCodeId
    if not imageCodeId:
        abort(404)
    #3,逻辑处理
    #3,1 生成验证码图片对象,验证吗的真实值,通过插件来生成
    name, text, image = captcha.generate_captcha()
    # 图片名字，验证码真实值以及图片对象

    #3,2 将图片验证码真实值使用编码存储到redis
    redis_store.set('imagechode_'+imageCodeId, text, ex=constants.IMAGE_CODE_REDIS_EXPIRES)

    #4,返回值处理
    #4,1 将图片对象返回给前端展示
    # return image

    """这里不能直接把图片返回给浏览器，需要转化为图片格式，不然的话浏览器会识别成文本类型，会造成乱码问题"""
    # 如果直接返回的话，浏览器会自动识别成文本格式，所以我们需要转化为图片格式返回
    response = make_response(image)
    response.headers["Content-Type"] = "image/jpeg"
    # 设置响应头中，image的数据类型为jpeg图片类型
    return response

"""第二步：当用户点击发送短信验证码时，会首先验证图片验证码是否正确，所以浏览器会把UUID和自己填写的图片验证码一起发送给服务器，当后台接收到这个数据时，首先通过UUID这个键取出对应的值，然后与用户填写的值对比，如果相同的话，说明用户图片验证码正确，此时发送短信验证码"""

@pap_bp.route('/sms_code',method=["POST"])
def send_sms():
    # 1.获取参数
    # 接受post请求
    param_dict = request.json
    mobile =param_dict.get("mobile")
    image_code = param_dict.get("image_code")
    image_code_id = param_dict.get("image_code_id")
    if not all(mobile, image_code, image_code_id):
        # 参数不足
        return jsonify(error=RET.PARAMERR, errmag="参数不全")

    # 校验手机号是否为真
    if not re.match("^1[3456789][0-9]{9}$", mobile):
        # 提示手机号不正确
        return jsonify(errno=RET.DATAERR, errmsg="手机号不正确")
    # 通过传入的图片编码去redis中查询真实的图片验证码图片
    try:
        real_image_code = redis_store.get("imagecode_"+image_code_id)
        # 如果能够取出来值，删除redis中缓存的内容
        if real_image_code:
            real_image_code = real_image_code.decode()
            redis_store.delete("imagecode_"+image_code_id)

    except Exception as e:
        current_app.logger.error(e)
        # 获取图片验证码失败
        return jsonify(errno=RET.DBERR, errmsg="获取图片验证码失败")
    # 判断验证码是否存在，也就是看验证码是否过期，因为我们设置的有效时长为5分钟
    if not real_image_code:
        # 验证码已过期
        return jsonify(errno=RET.NODATA, errmas="验证码已过期")

    # 进行验证码内容比对
    if image_code.lower() != real_image_code.lower():
        # 验证码输入错误
        return jsonify(errno=RET.DATAERR, errmsg="验证码输入错误")

    # 校验手机号
    try:
        # 查找数据库中，该电话号码是否存在
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询错误")
    if user:
        # 该手机号已经注册过了
        return jsonify(errno=RET.DATAEXIST, errmsg="该手机已注册")

    """第三步：我们自己生成一个六位验证码，通过第三方API将这个验证码发送给用户，然后用户填入验证码"""
    # 调用云通讯的SDK发送短信验证码
    # 生成一个6位的随机短信内容
    sms_code = random.randint(0, 999999)
    sms_code = "%06d" % sms_code

    result = CCP().sent_template_sms(mobile, [sms_code, constants.IMAGE_CODE_REDIS_EXPIRES/60], 1)

    if result != 0:
        # 发送短信验证码失败
        return jsonify(errno=RET.THIRDERR, errmsg="发送短信验证码失败")

    # 发送短信验证码成功
    # 存储短信验证码到redis
    try:
        redis_store.set("SMS_"+mobile, sms_code, ex=constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmrg="保存短信验证码到数据库异常")

    # 返回值处理，告知前端发送短信验证成功请注意查收
    return jsonify(errno=RET.OK, errmsg="发送短信验证成功")










